package com.dhms.uikit.media

import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.content.Intent.ACTION_GET_CONTENT
import android.content.Intent.CATEGORY_OPENABLE
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.dhms.uikit.AudioRecordBottomSheet
import com.dhms.uikit.R
import com.dhms.uikit.databinding.FragmentChooseOptionsBottomSheetBinding
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

/**
 * A button sheet to select the method of getting medias.
 *
 * You need to call #setMediaType(type) to set the type of medias which you want to choose and call #setOnMediaChosenCallback(callback) to register a callback on a media chosen.
 */
class MediaChooseOptionsBottomSheet(private val fragmentId: String) : BottomSheetDialogFragment() {

    private var _binding: FragmentChooseOptionsBottomSheetBinding? = null
    private val binding get() = _binding!!

    private var onMediaChosenCallback: ValueCallback<Array<Uri>>? = null

    private lateinit var fileChooserLauncher: ActivityResultLauncher<Intent>

    private var mediaType = "*/*"

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return BottomSheetDialog(
            requireContext(),
            R.style.Theme_UiKit_BottomSheetDialog,
        )
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentChooseOptionsBottomSheetBinding.inflate(inflater, container, false)

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.lifecycleOwner = viewLifecycleOwner

        fileChooserLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                onMediaChosenCallback?.onReceiveValue(
                    WebChromeClient.FileChooserParams.parseResult(
                        result.resultCode,
                        result.data
                    )
                )
                onMediaChosenCallback = null
                dismiss()
            }

        binding.cancelChooseWay.setOnClickListener {
            dismiss()
        }

        binding.justFileChooser = false
        if (mediaType.startsWith("image") || mediaType.startsWith("video")) {
            binding.chooseWayCapture.text = "拍照/录像"
            binding.chooseWayCapture.setOnClickListener {
                openCamera()
            }
            binding.chooseWaySelect.setOnClickListener {
                openFileChooser("image/*,video/*")
            }
        } else if (mediaType.startsWith("audio")) {
            binding.chooseWayCapture.text = "录 音"
            binding.chooseWayCapture.setOnClickListener {
                openAudioRecorder()
            }
            binding.chooseWaySelect.setOnClickListener {
                openFileChooser("audio/*")
            }
        } else {
            binding.justFileChooser = true
            binding.chooseWaySelect.setOnClickListener {
                openFileChooser(mediaType)
            }
        }
    }

    /**
     * Register a callback on a media chosen.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    fun setOnMediaChosenCallback(callback: ValueCallback<Array<Uri>>?): MediaChooseOptionsBottomSheet {
        onMediaChosenCallback = callback

        return this
    }

    /**
     * Sets the type of medias which you want to choose.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    fun setMediaType(type: String): MediaChooseOptionsBottomSheet {
        mediaType = type

        return this
    }

    private fun openFileChooser(type: String) {
        val intent = Intent(ACTION_GET_CONTENT)
        intent.addCategory(CATEGORY_OPENABLE)
        intent.type = type
        fileChooserLauncher.launch(intent)
    }

    private fun openCamera() {
        MediaActivity.startActivity(
            requireContext(),
            requireActivity(),
            fragmentId
        )
        onMediaChosenCallback = null
        dismiss()
    }

    private fun openAudioRecorder() {
        AudioRecordBottomSheet.newInstance(fragmentId, true).show(
            requireActivity().supportFragmentManager,
            AudioRecordBottomSheet.TAG
        )
        onMediaChosenCallback = null
        dismiss()
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onMediaChosenCallback?.onReceiveValue(arrayOf())
        onMediaChosenCallback = null
    }
}